ct_p_ellipse <-
function(data,
         color = c('red', 'green', 'blue'),
         labels = c('outer', 'inner'),
         savePDF = FALSE,
         ...) {
    color <- match.arg(color)
    labels <- match.arg(labels)
    n <- nrow(data)

    pts_max <- max(data[, 'PTS'])
    pts_min <- min(data[, 'PTS'])
    pts_diff <- pts_max - pts_min

    a <- vector(length = n)

    gd_max <- max(data[, 'GD'])
    gd_min <- min(data[, 'GD'])
    gd_diff <- gd_max - gd_min

    b <- a

    theta <- seq(0, 2 * pi, length = 512)

    x <- vector('list', length = n)
    y <- x

    if (savePDF != FALSE) {
        pdf(savePDF, width = 7.8, height = 11.2, paper = "a4", pointsize = 8)
    }

    if (labels == 'outer') {
        plot(seq(-100, 130, length = 100),
             seq(-100, 100, length = 100),
             type = 'n',
             xaxt = 'n',
             yaxt = 'n',
             xlab = 'PTS',
             ylab = 'GD',
             ...)
    } else {
        plot(seq(-100, 100, length = 100),
             seq(-100, 100, length = 100),
             type = 'n',
             xaxt = 'n',
             yaxt = 'n',
             xlab = 'PTS',
             ylab = 'GD',
             ...)
    }

    for (i in 1:n) {
        a[i] <- (data[i, 'PTS'] - pts_min) / pts_diff * 90 + 10
        b[i] <- (data[i, 'GD'] - gd_min) / gd_diff * 90 + 10

        x[[i]] <- a[i] * cos(theta)
        y[[i]] <- b[i] * sin(theta)

        if (color == 'red') {
            polygon(x[[i]], y[[i]], border = NA, col = '#FF000015')
        } else if (color == 'green') {
            polygon(x[[i]], y[[i]], border = NA, col = '#00FF0015')
        } else {
            polygon(x[[i]], y[[i]], border = NA, col = '#0000FF15')
        }
    }

    for (i in 1:n) {
        lines(x[[i]], y[[i]])

        if (labels == 'outer') {
            conn_x <- c(0, 87.5, 102.5)

            if (i < n / 2) {
                conn_y <- c(max(y[[i]]), 105 - 200 / n * i, 105 - 200 / n * i)
            } else {
                conn_y <- c(min(y[[i]]), 105 - 200 / n * i, 105 - 200 / n * i)
            }

            text(105, 105 - 200 / n * i, data[i, 1], pos = 4)
            lines(conn_x, conn_y)
        } else {
            if ((i + 3) %% 4 == 0) {
                text(0, b[i], data[i, 1])
            } else if ((i + 2) %% 4 == 0) {
                text(a[i], 0, data[i, 1], srt = - 90)
            } else if ((i + 1) %% 4 == 0) {
                text(0, - b[i], data[i, 1], srt = - 180)
            } else {
                text(- a[i], 0, data[i, 1], srt = - 270)
            }
        }
    }

    if (savePDF != FALSE) {
        dev.off()
    }
}
